/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <hi_stdlib.h>
#include <hisignalling_protocol.h>
#include <hi_uart.h>
#include <app_demo_uart.h>
#include <iot_uart.h>
#include <hi_gpio.h>
#include <hi_io.h>
#include "iot_gpio_ex.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_uart.h"
#include "iot_pwm.h"
#include "string.h"
#include "stdlib.h"
#include "hi_pwm.h"

#define UART_TASK_STACK_SIZE 1024 * 8
#define UART_TASK_PRIO osPriorityNormal
#define UART_BUFF_SIZE 1000

unsigned char step=0;
uint8_t uart_buff[UART_BUFF_SIZE] = {0};
uint8_t *uart_buff_ptr = uart_buff;
unsigned short Livling_LED_Duty=20000;
// enum{
//     WAIT,
// 	Harmful_Garbage,
//     Other_Garbage,
//     Kitchen_Garbage,
//     Recyclable_Garbage
// };

/*Hello world*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_i2c.h"
#include "iot_gpio.h"
#include "iot_errno.h"
#include "oled_ssd1306.h"
#define LED_INTERVAL_TIME_US 300000
#define AHT20_BAUDRATE (400 * 1000)
#define AHT20_I2C_IDX 0

#define LED_TEST_GPIO 9 // for hispark_pegasus
/*舵机控制*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "hi_io.h"
#include "hi_time.h"
/*门锁控制GPIO定义*/
#define IOT_GPIO_SERVO 6
#define IOT_GPIO_SERVO1 7
#define IOT_GPIO_SERVO2 8
#define GPIO2 2
#define COUNT 10
#define TASK_STAK_SIZE    (1024*10)
/*电机控制初始化定义GPIO*/
#define GPIO0 0
#define GPIO1 1
#define GPIO3 3
#define GPIO10 10
#define GPIOFUNC 0
/*电机控制程序*/
void gpio_control (unsigned int gpio, IotGpioValue value)
{
    hi_io_set_func(gpio, GPIOFUNC);
    IoTGpioSetDir(gpio, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(gpio, value);
}

void car_backward(void)
{
    gpio_control(GPIO0, IOT_GPIO_VALUE0);
    gpio_control(GPIO1, IOT_GPIO_VALUE1);
    gpio_control(GPIO3, IOT_GPIO_VALUE0);
    gpio_control(GPIO10, IOT_GPIO_VALUE1);
}

void car_forward(void)
{
    gpio_control(GPIO0, IOT_GPIO_VALUE1);
    hi_udelay(2000);

    gpio_control(GPIO0, IOT_GPIO_VALUE0);
    gpio_control(GPIO1, IOT_GPIO_VALUE1);
    hi_udelay(2000);

    gpio_control(GPIO1, IOT_GPIO_VALUE0);
    gpio_control(GPIO3, IOT_GPIO_VALUE1);
    hi_udelay(2000);

    gpio_control(GPIO3, IOT_GPIO_VALUE0);
    gpio_control(GPIO10, IOT_GPIO_VALUE1);
    hi_udelay(2000);

    gpio_control(GPIO10, IOT_GPIO_VALUE0);
}

void car_left(void)
{
    gpio_control(GPIO10, IOT_GPIO_VALUE1);
    //osDelay(1);
    hi_udelay(2000);
    gpio_control(GPIO10, IOT_GPIO_VALUE0);
    gpio_control(GPIO3, IOT_GPIO_VALUE1);
    //osDelay(1);
    hi_udelay(2000);
    gpio_control(GPIO3, IOT_GPIO_VALUE0);
    gpio_control(GPIO1, IOT_GPIO_VALUE1);
    //osDelay(1);
    hi_udelay(2000);
    gpio_control(GPIO1, IOT_GPIO_VALUE0);
    gpio_control(GPIO0, IOT_GPIO_VALUE1);
    //osDelay(1);
    hi_udelay(2000);
    gpio_control(GPIO0, IOT_GPIO_VALUE0);
}

void car_right(void)
{
    gpio_control(GPIO0, IOT_GPIO_VALUE1);
    gpio_control(GPIO1, IOT_GPIO_VALUE0);
    gpio_control(GPIO3, IOT_GPIO_VALUE0);
    gpio_control(GPIO10, IOT_GPIO_VALUE0);
}

void car_stop(void)
{
    gpio_control(GPIO0, IOT_GPIO_VALUE1);
    gpio_control(GPIO1, IOT_GPIO_VALUE1);
    gpio_control(GPIO3, IOT_GPIO_VALUE1);
    gpio_control(GPIO10, IOT_GPIO_VALUE1);
}
/*电机反转*/
void Robotfan(void)
{
    printf("start test l9110s\r\n");
    unsigned int time = 500;
    for(int i=0; i<2000; i++)
    {
        //car_forward();
        car_left();
    }
}
/*电机正转*/
void Robotzheng(void)
{
    printf("start test l9110s\r\n");
    unsigned int time = 500;
    for(int i=0;i<2000;i++)
    {
        //car_forward();
        car_forward();
    }
}
/*门锁控制初始化*/
void door(void)
{
    /*GPIO7实验*/
    IoTGpioInit(IOT_GPIO_SERVO1);
    IoSetFunc(IOT_GPIO_SERVO1,0);
    IoTGpioSetDir(IOT_GPIO_SERVO1,IOT_GPIO_DIR_OUT);
    /*GPIO8实验LED2*/
    IoTGpioInit(IOT_GPIO_SERVO2);
    IoSetFunc(IOT_GPIO_SERVO2,0);
    IoTGpioSetDir(IOT_GPIO_SERVO2,IOT_GPIO_DIR_OUT);
}
void set_angle1(unsigned int duty)
{
    unsigned int time = 20000;
    //IoTGpioSetDir(GPIO2, IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(IOT_GPIO_SERVO, IOT_GPIO_VALUE1);
    hi_udelay(duty);
    IoTGpioSetOutputVal(IOT_GPIO_SERVO, IOT_GPIO_VALUE0);
    hi_udelay(time - duty);
}

/* Turn 45 degrees to the left of the steering gear
1、依据角度与脉冲的关系，设置高电平时间为1000微秒
2、不断地发送信号，控制舵机向左旋转45度
*/
void engine_turn_left_451(void)
{
    unsigned int angle = 1000;
    for (int i = 0; i < COUNT; i++) {
        set_angle1(angle);
    }
}

/* Turn 90 degrees to the left of the steering gear
1、依据角度与脉冲的关系，设置高电平时间为500微秒
2、不断地发送信号，控制舵机向左旋转90度
*/
void engine_turn_left_901(void)
{
    unsigned int angle = 500;
    for (int i = 0; i < COUNT; i++) {
        set_angle1(angle);
    }
}

/* Turn 45 degrees to the right of the steering gear
1、依据角度与脉冲的关系，设置高电平时间为2000微秒
2、不断地发送信号，控制舵机向右旋转45度
*/
void engine_turn_right_451(void)
{
    unsigned int angle = 2000;
    for (int i = 0; i < COUNT; i++) {
        set_angle1(angle);
    }
}

/* Turn 90 degrees to the right of the steering gear
1、依据角度与脉冲的关系，设置高电平时间为2500微秒
2、不断地发送信号，控制舵机向右旋转90度
*/
void engine_turn_right_901(void)
{
    unsigned int angle = 2500;
    for (int i = 0; i < COUNT; i++) {
        set_angle1(angle);
    }
}

/* The steering gear is centered
1、依据角度与脉冲的关系，设置高电平时间为1500微秒
2、不断地发送信号，控制舵机居中
*/
void regress_middle1(void)
{
    unsigned int angle = 1500;
    for (int i = 0; i < COUNT; i++) {
        set_angle1(angle);
    }
}

/* 任务实现 */
void RobotTask1(void* parame)
{
    (void)parame;
    unsigned int time = 200;
    //printf("start test sg90\r\n");
    //engine_turn_left_45();
    //printf("Turn 45 degrees to the left of the steering gear\r\n");
    //osDelay(time);
    engine_turn_left_451();
    ("Turn 90 degrees to the left of the steering gear\r\n");
    osDelay(time);
    //regress_middle();
    //printf("The steering gear is centered");
    //osDelay(time);
    //engine_turn_right_45();
    //printf("Turn 45 degrees to the left of the steering gear\r\n");
    //osDelay(time);
    engine_turn_right_451();
    printf("Turn 90 degrees to the left of the steering gear\r\n");
    osDelay(time);
    //regress_middle();
    //printf("The steering gear is centered");
}


static void RobotDemo1(void)
{
    osThreadAttr_t attr;

    attr.name = "RobotTask1";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = TASK_STAK_SIZE;
    attr.priority = osPriorityNormal;

    if (osThreadNew(RobotTask1, NULL, &attr) == NULL) {
        printf("[RobotDemo] Falied to create RobotTask1!\n");
    }
}

static void Uart1GpioCOnfig2(void)
{
    IoSetFunc(HI_IO_NAME_GPIO_11, IOT_IO_FUNC_GPIO_11_UART2_TXD);
    IoSetFunc(HI_IO_NAME_GPIO_12, IOT_IO_FUNC_GPIO_12_UART2_RXD);
}

/*OLED控制*/
static void OledmentTask2(const char *arg)
{
    (void)arg;
    OledInit();
    OledFillScreen(0);
    IoTI2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);

    OledShowString(20, 3, "ABCD", 1); /* 屏幕第20列3行显示1行 */
}

static void OledDemo2(void)
{
    osThreadAttr_t attr;
    attr.name = "OledmentTask2";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096; /* 任务大小4096 */
    attr.priority = osPriorityNormal;

    if (osThreadNew(OledmentTask2, NULL, &attr) == NULL) {
        printf("[OledDemo] Falied to create OledmentTask!\n");
    }
}
enum{
    WAIT,
	Open_Alarm,
    Close_Alarm,
    Kitchen_LED_Open,
    Kitchen_LED_Close,
    Living_LED_Open,
    Living_LED_Close,
    LED_Add,
    LED_Reduce
};


//检测串口指令
void Garbage_Uart_Cmd2(char *str)      
{
    char  *Str;
    unsigned char ID=255;
	
    Str=&str[1];//定位到指令的数字部分“U1”
    ID=atoi(Str);
	
	if(strstr((const char *)str,"G")!=NULL)			//如果字符串str中包含有“G”
	{
		switch(ID)
		{
			case 1:	// 开灯
				step = Open_Alarm;
                //RobotDemo1();
                //IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
                //IoTGpioSetOutputVal(IOT_GPIO_SERVO1, IOT_GPIO_VALUE1);
                IoTGpioSetOutputVal(IOT_GPIO_SERVO2, IOT_GPIO_VALUE1);
                //TaskMsleep(2000);
                printf("Open_Alarm\r\n");
				break;
			case 2:	// 关灯
				step = Close_Alarm;
                //IoTGpioSetOutputVal(LED_TEST_GPIO, 1);
                //IoTGpioSetOutputVal(IOT_GPIO_SERVO1, IOT_GPIO_VALUE0);
                IoTGpioSetOutputVal(IOT_GPIO_SERVO2, IOT_GPIO_VALUE0);
                //OledDemo2();
                //TaskMsleep(2000);
                printf("Close_Alarm\r\n");

				break;
			case 3:	// 打开窗帘
				step = Kitchen_LED_Open;
                //engine_turn_left_451();
                //OledDemo2();
                /*循环  电机正转*/
                Robotfan();
                //IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
                //TaskMsleep(2000);
                printf("Kitchen_LED_Open\r\n");
				break;
			case 4:	//  关闭窗帘
				step = Kitchen_LED_Close;
                //engine_turn_right_451();
                //OledFillScreen(0);
                /*循环  电机反转*/
                Robotzheng();
                //TaskMsleep(2000);
                printf("Kitchen_LED_Close\r\n");

				break;
			default:
				printf("%s ERROR",str);
                step =  WAIT;
				break;
		}
	}
    memset(uart_buff,0,sizeof(uart_buff));
}



// static const char *data = "Hello, BearPi!\r\n";

static void UART_Task2(void)
{
    uint32_t ret;

    IotUartAttribute uart_attr = {

        //baud_rate: 9600
        .baudRate = 9600,

        //data_bits: 8bits
        .dataBits = 8,
        .stopBits = 1,
        .parity = 0,
    };
    door();
    Uart1GpioCOnfig2();
    /*LED*/
    IoTGpioInit(LED_TEST_GPIO);
    IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT);
    ret = IoTUartInit(HI_UART_IDX_2, &uart_attr);

    /*实验窗帘的控制*/




    //OledDemo2();
    if (ret != HI_ERR_SUCCESS)
    /*{
        printf("Failed to init uart! Err code = %d\n", ret);
        return;
    }*/
    printf("UART Test Start\n");
    //OledDemo2();
    while (1)
    {
        printf("=======================================\r\n");
        printf("*************UART_example**************\r\n");
        printf("=======================================\r\n");

        /*实验电机转动打开和关闭窗帘*/
        //engine_turn_left_451();
        //Robotzheng();


        // //通过串口2发送数据
        // UartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)data, strlen(data));

        //通过串口2接收数据
        IoTUartRead(HI_UART_IDX_2, uart_buff_ptr, UART_BUFF_SIZE);
        Garbage_Uart_Cmd2((char *)uart_buff_ptr);
        //OledDemo2();

        //IoTGpioSetOutputVal(IOT_GPIO_SERVO1, IOT_GPIO_VALUE1);
        //TaskMsleep(2000);
        //IoTGpioSetOutputVal(IOT_GPIO_SERVO1, IOT_GPIO_VALUE0);
        //TaskMsleep(2000);

        //IoTGpioSetOutputVal(IOT_GPIO_SERVO2, IOT_GPIO_VALUE1);
        //TaskMsleep(200);
        //IoTGpioSetOutputVal(IOT_GPIO_SERVO2, IOT_GPIO_VALUE0);
        //TaskMsleep(200);
        printf("Uart2 read data:%s", uart_buff_ptr);
        usleep(500000);
    }
}

static void UART_ExampleEntry(void)
{

    osThreadAttr_t attr;

    attr.name = "UART_Taska";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = UART_TASK_STACK_SIZE;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)UART_Task2, NULL, &attr) == NULL)
    {
        printf("[ADCExample] Falied to create UART_Taska!\n");
    }
}

SYS_RUN(UART_ExampleEntry);
//APP_FEATURE_INIT(UART_ExampleEntry);